package org.gap.wizards.utils;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Collection;
import java.util.Properties;

public class PersistenceUtils {
	private static final String SAVE_FILE = "save.dat";
	public static final File HOME_DIRECTORY;

	static {
		if (System.getProperty("save.dir") == null) {
			HOME_DIRECTORY = new File(System.getProperty("user.home"));
		} else {
			HOME_DIRECTORY = new File(System.getProperty("save.dir"));
			if (!HOME_DIRECTORY.exists()) {
				HOME_DIRECTORY.mkdirs();
			}
		}
	}

	public static File getPlayerFile() {
		File savePath = ensurePath(HOME_DIRECTORY, "wizard", "save");
		return new File(savePath, "player.dat");
	}

	public static File getMapFile(String id) throws IOException {
		File savePath = ensurePath(HOME_DIRECTORY, "wizard", "save", "map");
		File file = new File(savePath, id + ".map");
		return file;
	}

	private static File ensurePath(File currentDirectory, String... path) {
		for (String each : path) {
			currentDirectory = new File(currentDirectory, each);
			if (!currentDirectory.exists()) {
				currentDirectory.mkdir();
			}
		}
		return currentDirectory;
	}

	public static void deleteAll() {
		deletePlayer();
		deleteData();
		File directory = ensurePath(HOME_DIRECTORY, "wizard", "save", "map");
		for (String each : directory.list()) {
			File file = new File(directory, each);
			deleteFile(file);
		}
		deleteSave();
	}

	public static void deletePlayer() {
		File playerFile = getPlayerFile();
		deleteFile(playerFile);
	}

	public static void deleteMaps(Collection<String> mapIds) throws IOException {
		for (String each : mapIds) {
			delete(each);
		}
	}

	public static void delete(String id) throws IOException {
		File file = getMapFile(id);
		deleteFile(file);
	}

	private static void deleteFile(File file) {
		if (file.exists()) {
			file.delete();
		}
		if (file.exists()) {
			throw new PersistenceException("Unable to delete map " + file.getName());
		}
	}

	@SuppressWarnings("serial")
	public static class PersistenceException extends RuntimeException {

		public PersistenceException(String error) {
			super(error);
		}
	}

	public static String getField(String field) throws IOException {
		Properties savedData = new Properties();
		FileReader dataReader = new FileReader(getSavedDataFile());
		savedData.load(dataReader);
		dataReader.close();
		return savedData.getProperty(field);
	}

	public static void setField(String field, Object value) throws IOException {
		Properties savedData = new Properties();
		File savedDataFile = getSavedDataFile();
		if (savedDataFile.exists()) {
			FileReader dataReader = new FileReader(savedDataFile);
			savedData.load(dataReader);
			dataReader.close();
		}
		savedData.put(field, value.toString());

		FileWriter dataWriter = new FileWriter(savedDataFile);
		savedData.store(dataWriter, "");
		dataWriter.flush();
		dataWriter.close();
	}

	private static File getSavedDataFile() {
		File savedDataPath = ensurePath(HOME_DIRECTORY, "wizard", "save");
		return new File(savedDataPath, "Props.dat");
	}

	public static int getIntField(String field) throws IOException {
		return Integer.parseInt(getField(field));
	}

	private static void deleteData() {
		deleteFile(getSavedDataFile());
	}

	public static boolean hasSave() {
		return new File(ensurePath(HOME_DIRECTORY, "wizard"), SAVE_FILE).exists();
	}

	public static void createSave() {
		try {
			File file = new File(ensurePath(HOME_DIRECTORY, "wizard"), SAVE_FILE);
			file.createNewFile();
		} catch (IOException ioe) {
			ioe.printStackTrace();
		}
	}

	public static void deleteSave() {
		File file = new File(ensurePath(HOME_DIRECTORY, "wizard"), SAVE_FILE);
		deleteFile(file);
	}
}